package request

import (
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
	"lab.com/conf"
	"lab.com/consts"
	"lab.com/define/errorcode"
)

// LoginInputReq 用户登录请求参数
type LoginInputReq struct {
	Phone    string `json:"phone" form:"phone" validate:"required,len=11,checkPhoneRex" comment:"手机号" example:"13000000001"`
	Password string `json:"password" form:"password" validate:"required" comment:"密码" example:"123456"`
}

// LoginRes 用户登录返回参数
type LoginRes struct {
	Token    string   `json:"token"`
	UserInfo UserInfo `json:"user_info"`
}

// UserInfo 用户信息
type UserInfo struct {
	ID         int    `json:"id"`
	Username   string `json:"username"`    // 用户名
	Phone      string `json:"phone"`       // 绑定手机号
	Email      string `json:"email"`       // 邮箱
	Avatar     string `json:"avatar"`      // 头像
	Gender     int    `json:"gender"`      // 姓名 0 未知 10 男 20 女
	GenderDesc string `json:"gender_desc"` // 姓名 0 未知 10 男 20 女
	Status     int    `json:"status"`      // 账户状态 10 正常 0 删除
	IsUse      int    `json:"is_use"`      // 账户状态 10 正常 20 禁用
	IsManager  int    `json:"is_manager"`  // 是否是管理员 10 是 0 不是 20超管
	Role       int    `json:"role"`        // 角色
	RoleName   string `json:"role_name"`   // 角色
	Address    string `json:"address"`     // 通讯地址
	Subject    string `json:"subject"`     // 所在学科
	Postion    string `json:"position"`    // 职位
	CreateTime string `json:"create_time"` // 创建时间
	UpdateTime string `json:"update_time"` // 修改时间
	Content    string `json:"content"`     // 内容
}

// CheckInputParams return input params
func (user *LoginInputReq) CheckInputParams(c *gin.Context) error {

	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}
	return nil
}

// ContentEditReq 用户编辑自我介绍信息参数
type ContentEditReq struct {
	UserID  int    `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"10"`
	Content string `json:"content" form:"content" validate:"required" comment:"内容"`
}

// CheckInputParams return input params
func (user *ContentEditReq) CheckInputParams(c *gin.Context) error {

	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}
	return nil
}

// InfoUpdateReq 用户信息更新请求参数
type InfoUpdateReq struct {
	UserID   int    `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"10"`
	Username string `json:"username" form:"username" validate:"required,max=30" comment:"用户名" example:"张三"`
	Phone    string `json:"phone" form:"phone" validate:"required,checkPhoneRex" comment:"手机号" example:"13100000001"`
	Gender   int    `json:"gender" form:"gender" validate:"oneof=0 10 20" comment:"性别" example:"10"`
	Address  string `json:"address" form:"address" validate:"max=50" comment:"通讯地址" example:"北京理工大学" `
	Avatar   string `json:"avatar" form:"avatar" validate:"max=255" comment:"头像" example:"1.jpg" `
	Subject  string `json:"subject" form:"subject" validate:"required,max=10" comment:"所在学科" example:"网络空间安全" `
	Email    string `json:"email" form:"email" validate:"max=30" comment:"邮箱" example:"xxx@qq.com" `
	Position string `json:"position" form:"position" validate:"max=10" comment:"职称" example:"网络空间安全" `
	// EnrollmentYear int    `json:"enrollment_year" form:"enrollment_year" validate:"required" comment:"入学年份" example:"2020"`
}

// CheckInputParams return input params
func (user *InfoUpdateReq) CheckInputParams(c *gin.Context) error {

	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}
	return nil
}

// UserInfoReq 用户信息请求参数
type UserInfoReq struct {
	UserID int `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"10"`
}

// BasicUserInfo 用户显示基本信息
type BasicUserInfo struct {
	ID             int    `json:"id"`
	Username       string `json:"username"`        // 用户名
	Phone          string `json:"phone"`           // 绑定手机号
	Email          string `json:"email"`           // 邮箱
	Avatar         string `json:"avatar"`          // 头像
	Gender         int    `json:"gender"`          // 姓名 0 未知 10 男 20 女
	GenderDesc     string `json:"gender_desc"`     // 姓名 0 未知 10 男 20 女
	Status         int    `json:"status"`          // 账户状态 10 正常 0 删除
	IsUse          int    `json:"is_use"`          // 账户状态 10 正常 20 禁用
	IsManager      int    `json:"is_manager"`      // 是否是管理员 10 是 0 不是
	Role           int    `json:"role"`            // 角色
	RoleName       string `json:"role_name"`       // 角色
	Address        string `json:"address"`         // 通讯地址
	Subject        string `json:"subject"`         // 所在学科
	CreateTime     string `json:"create_time"`     // 创建时间
	UpdateTime     string `json:"update_time"`     // 修改时间
	Content        string `json:"content"`         // 内容
	Position       string `json:"position"`        // 职称
	EnrollmentYear int    `json:"enrollment_year"` //入学年份
}

// CheckInputParams return input params
func (user *UserInfoReq) CheckInputParams(c *gin.Context) error {

	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}
	return nil
}

// UserListReq 用户列表请求参数
type UserListReq struct {
	RoleID int `json:"role_id" form:"role_id" validate:"oneof=0 10 20 30 40" comment:"用户角色" example:"10"`
}

// SimpleUserInfo 用户简单信息
type SimpleUserInfo struct {
	ID       int    `json:"id"`
	Username string `json:"username"` // 用户名
	Avatar   string `json:"avatar"`   // 头像
}

// UserInfoList 用户列表
type UserInfoList struct {
	Count int              `json:"count"`
	List  []SimpleUserInfo `json:"list"`
}

// CheckInputParams return input params
func (user *UserListReq) CheckInputParams(c *gin.Context) error {

	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}
	return nil
}

// UserAddReq 用户新增请求参数
type UserAddReq struct {
	Username       string `json:"username" form:"username" validate:"required,max=10" comment:"用户名" example:"郭梦洁" `
	Phone          string `json:"phone" form:"phone" validate:"required,checkPhoneRex" comment:"手机号" example:"13100000002"`
	UserRole       int    `json:"user_role" form:"user_role" validate:"oneof=0 10 20 30 40 50" comment:"用户角色" example:"10"`
	IsUse          int    `json:"is_use" form:"is_use" validate:"oneof=0 10" comment:"是否禁用" example:"10"`
	IsManager      int    `json:"is_manager" form:"is_manager" validate:"oneof=0 10" comment:"是否是管理员" example:"10"`
	EnrollmentYear int    `json:"enrollment_year" form:"enrollment_year" validate:"" comment:"入学年份" example:"2020"`
}

// CheckInputParams return input params
func (user *UserAddReq) CheckInputParams(c *gin.Context) error {

	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}

	// 管理员用户才有权限新增
	managerType := c.GetHeader(consts.CtxManageType)
	if mt, err := strconv.Atoi(managerType); err != nil {
		return err
	} else if mt == consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, errorcode.RolePermissionRequiredMsg, nil)
	}
	return nil
}

// ListInManageReq 管理页面用户列表
type ListInManageReq struct {
	Username string `json:"username" form:"username" comment:"用户名" example:"郭梦洁" `
	RoleID   int    `json:"role_id" form:"role_id" validate:"oneof=0 10 20 30 40" comment:"用户角色" example:"10"`
	Phone    string `json:"phone" form:"phone" validate:"omitempty,checkPhoneRex" comment:"手机号" example:"13000000001"`
	PageOffset
}

// UserManageList 用户管理列表
type UserManageList struct {
	Count int              `json:"count"`
	List  []UserManageInfo `json:"list"`
}

// UserManageInfo 用户管理信息
type UserManageInfo struct {
	ID             int    `json:"id"`
	Username       string `json:"username"`        // 用户名
	Phone          string `json:"phone"`           // 手机号
	UserRole       int    `json:"user_role"`       // 用户角色
	IsUse          int    `json:"is_use"`          // 是否启用
	IsManager      int    `json:"is_manager"`      // 是否是管理员，0普通用户，10管理员，20超管
	EnrollmentYear int    `json:"enrollment_year"` //入学年份
}

// CheckInputParams return input params
func (user *ListInManageReq) CheckInputParams(c *gin.Context) error {
	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}
	user.ParseOffset()

	// 管理员才有权限
	managerType := c.GetHeader("manage-type")
	if mt, err := strconv.Atoi(managerType); err != nil {
		return err
	} else if mt == consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, errorcode.RolePermissionRequiredMsg, nil)
	}
	return nil
}

// EditInManageReq 管理页面用户信息更改
type EditInManageReq struct {
	UserID         int    `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"14" `
	Username       string `json:"username" form:"username" validate:"required" comment:"用户名" example:"郭梦洁" `
	Phone          string `json:"phone" form:"phone" validate:"required,checkPhoneRex" comment:"手机号" example:"13100000002"`
	UserRole       int    `json:"user_role" form:"user_role" validate:"oneof=0 10 20 30 40 50" comment:"用户角色" example:"10"`
	IsUse          int    `json:"is_use" form:"is_use" validate:"oneof=0 10" comment:"是否禁用" example:"10"`
	IsManager      int    `json:"is_manager" form:"is_manager" validate:"oneof=0 10" comment:"是否是管理员" example:"10"`
	EnrollmentYear int    `json:"enrollment_year" form:"enrollment_year" validate:"required" comment:"入学年份" example:"2020"`
}

// CheckInputParams return input params
func (user *EditInManageReq) CheckInputParams(c *gin.Context) error {
	ctx := conf.Span(c, "request user edit in manage", nil)
	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}

	// 获取用户角色
	userModel := conf.LabGen.User
	info, err := userModel.WithContext(ctx).Where(userModel.ID.Eq(user.UserID)).First()
	if err != nil {
		return err
	}

	// 超管可以删除所有用户，普通管理员只能删除普通用户
	managerType := c.GetHeader(consts.CtxManageType)
	if mt, err := strconv.Atoi(managerType); err != nil {
		return err
	} else if mt == consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, errorcode.RolePermissionRequiredMsg, nil)
	} else if mt == consts.RoleAdmin && info.IsManager != consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, "您无权删除其他管理员用户", nil)
	}
	return nil
}

// UserIsUseReq 用户账号是否使用请求参数
type UserIsUseReq struct {
	UserID int `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"14" `
	IsUse  int `json:"is_use" form:"is_use" validate:"oneof=0 10" comment:"0禁用 10启用" example:"10" `
}

// CheckInputParams return input params
func (user *UserIsUseReq) CheckInputParams(c *gin.Context) error {
	ctx := conf.Span(c, "request user delete", nil)
	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}

	// 获取用户角色
	userModel := conf.LabGen.User
	info, err := userModel.WithContext(ctx).Where(userModel.ID.Eq(user.UserID)).First()
	if err != nil {
		return err
	}

	// 超管可以禁用/启用所有用户，普通管理员只能禁用/启用普通用户
	managerType := c.GetHeader(consts.CtxManageType)
	if mt, err := strconv.Atoi(managerType); err != nil {
		return err
	} else if mt == consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, errorcode.RolePermissionRequiredMsg, nil)
	} else if mt == consts.RoleAdmin && info.IsManager != consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, "您无权禁用/启用其他管理员用户", nil)
	}
	return nil
}

// UserDeleteReq 用户删除请求参数
type UserDeleteReq struct {
	UserID int `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"14" `
}

// CheckInputParams return input params
func (user *UserDeleteReq) CheckInputParams(c *gin.Context) error {
	ctx := conf.Span(c, "request user delete", nil)
	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}

	// 获取用户角色
	userModel := conf.LabGen.User
	info, err := userModel.WithContext(ctx).Where(userModel.ID.Eq(user.UserID)).First()
	if err != nil {
		return err
	}

	// 超管可以删除所有用户，普通管理员只能删除普通用户
	managerType := c.GetHeader(consts.CtxManageType)
	if mt, err := strconv.Atoi(managerType); err != nil {
		return err
	} else if mt == consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, errorcode.RolePermissionRequiredMsg, nil)
	} else if mt == consts.RoleAdmin && info.IsManager != consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, "您无权删除其他管理员用户", nil)
	}
	return nil
}

// UserIsManagerReq 用户是否成为管理员请求参数
type UserIsManagerReq struct {
	UserID    int `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"14" `
	IsManager int `json:"is_manager" form:"is_manager" validate:"oneof=0 10" comment:"管理员类型，0普通用户，10管理员" example:"10" `
}

// CheckInputParams return input params
func (user *UserIsManagerReq) CheckInputParams(c *gin.Context) error {
	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}

	// 超级管理员才有权限，设置用户为管理员
	managerType := c.GetHeader(consts.CtxManageType)
	if mt, err := strconv.Atoi(managerType); err != nil {
		return err
	} else if mt != consts.RoleSuperAdmin {
		return errorcode.New(errorcode.ErrRolePermissionRequired, errorcode.RolePermissionRequiredMsg, nil)
	}
	return nil
}

// PasswordResetReq 用户重置密码请求参数
type PasswordResetReq struct {
	UserID int `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"14" `
}

// CheckInputParams return input params
func (user *PasswordResetReq) CheckInputParams(c *gin.Context) error {
	ctx := conf.Span(c, "request user password reset", nil)
	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}

	// 获取用户角色
	userModel := conf.LabGen.User
	info, err := userModel.WithContext(ctx).Where(userModel.ID.Eq(user.UserID)).First()
	if err != nil {
		return err
	}

	// 超管可以删除所有用户，普通管理员只能删除普通用户
	managerType := c.GetHeader(consts.CtxManageType)
	if mt, err := strconv.Atoi(managerType); err != nil {
		return err
	} else if mt == consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, errorcode.RolePermissionRequiredMsg, nil)
	} else if mt == consts.RoleAdmin && info.IsManager != consts.RoleUser {
		return errorcode.New(errorcode.ErrRolePermissionRequired, "您无权删除其他管理员用户", nil)
	}
	return nil
}

// PasswordEditReq 修改密码
type PasswordEditReq struct {
	UserID          int    `json:"user_id" form:"user_id" validate:"required" comment:"用户id" example:"10"`
	OldPassword     string `json:"old_password" form:"old_password" validate:"required" comment:"旧密码"`
	NewPassword     string `json:"new_password" form:"new_password" validate:"required" comment:"新密码"`
	ConfirmPassword string `json:"confirm_password" form:"confirm_password" validate:"required" comment:"确认新密码"`
}

// CheckInputParams return input params
func (user *PasswordEditReq) CheckInputParams(c *gin.Context) error {

	if err := c.ShouldBind(user); err != nil {
		return err
	}
	if errs, err := Validate(user); err != nil {
		return errorcode.New(errorcode.ErrParams, strings.Join(errs, ","), nil)
	}
	if user.NewPassword != user.ConfirmPassword {
		return errorcode.New(errorcode.ErrParams, "两次输入的新密码不一致，请重新输入", nil)
	}
	return nil
}
